% Load Agata's list of training images
trainingImageList = importdata('imageList.txt');

% choose from the following list of cameras
% TODO: 2 5  1147 1217 1411 3544 4169 4170 6727 7270 7271 7272 8208 8210
% 8283 8445 8675 8794 9164 9481 9507 9704 9843 9864 9883 10047 10888 
% 10892 17023 19016 19119 19171 19172 19200 19240 19443 19453

% When done, move to this list...
% DONE

whichCamera = 1147;

fNames = {};
searchString = ['image/' num2str(whichCamera) '/'];
% get a list of images
for ix = 1:length(trainingImageList)
      if ~isempty(strfind(trainingImageList{ix},searchString))
          fNames{end+1} = trainingImageList{ix}
      end
end

% Clear some variables for the next camera
clear posRECTS
clear negRECTS

%% let's get 5 images per iteration of our incremental training:
figure(1);clf;
currImage = 1;
numRects = 0;
clf
posRECTS = [];
posHOGS = [];
currImage = 1+floor(rand(1,1).* length(fNames));

while numRects < 5
    fName = fNames{currImage};
    im = imread(fName);
    imagesc(im);
    title('type (r) to outline another person, or (n) to go to the next image');
    userInput = input('type (r) to outline another person, or (n) to go to the next image ','s');
    switch userInput
        case 'r',
            disp('r');
            numRects = numRects + 1;
            r = getRectFromUser(im);
            [hog rectData] = makeHOGandRECT(im,r);
            posHOGS(:,numRects) = hog(:);
            rectData.fName = fName;
            posRECTS{end+1} = rectData;
        case 'n',
            currImage = 1+floor(rand(1,1).* length(fNames));
            disp('n');
        otherwise
            disp(['unknown input: ' userInput]);
    end
end
disp('Done with First 5 Positive Examples!');

%% understand normal rectangle sizes, 
% in order to get appropriate negative examples
R = [];
for ix = 1:numRects
    R(ix,:) = posRECTS{ix}.r;
end
posRECTexamples = R;

sizeA = mean(R(:,3));
sizeB = mean(R(:,4));

% Now choose arbitrary rectangles in the scene with that size.
negRECTS = [];
numNegExamples = 100;
for ix = 1:numNegExamples
       
    %pick the rectangle at random
    raMin = 1+floor(rand(1,1) .* (size(im,2)-sizeA));
    rbMin = 1+floor(rand(1,1) .* (size(im,1)-sizeB));
    
    raMax = raMin + sizeA;
    rbMax = rbMin + sizeB;
    ra = round(raMin):round(raMax);
    rb = round(rbMin):round(rbMax);
    
    % pick the image at random
    whichImage = floor(rand(1,1) .* currImage) + 1;
    fName = fNames{whichImage}
    im = imread(fNames{whichImage});  
    
    negR = [raMin rbMin sizeA sizeB];
    [hog rectData] = makeHOGandRECT(im,negR);
    negHOGS(:,ix) = hog(:);
    rectData.fName = fName;
    negRECTS{end+1} = rectData;
end
disp('Done choosing first 100 random negative examples');

% now do svm

[W, xMean] = doHOGsvm(posHOGS, negHOGS);

origPosHOGS = posHOGS;
origNegHOGS = negHOGS;  
% save these for debugging the iterative bit
posHOGS = origPosHOGS;
negHOGS = origNegHOGS;

%%
for ix = 1:20
    % draw the current HOG feature.  gives user something to look at while
    % we compute stuff...
    figure(2);
    clf;
    imagesc(vl_hog('render', single(reshape(W(1:end-1),size(hog)))));
    axis off;
    title('current hog feature');
    
    % reshow orig figure window to draw things into
    figure(1);
    % get a new image to try it on
    badImage = 1;
    while badImage
        currImage = 1+floor(rand(1,1).* length(fNames));
        %disp('cheating for Towson camera');
        %currImage = 1+floor(rand(1,1).* 600);
        fName = fNames{currImage}
        im = imread(fName);
        imagesc(im);
        title(fName);
        pause(0.01);
        userInput = input('use image y or n?','s');
        switch userInput
            case 'y',
                badImage = 0;
            otherwise
                fprintf('.');
        end
    end
    
    % train classifier:
    [W, xMean] = doHOGsvm(posHOGS, negHOGS);
    
    % apply to new image.
    [newPosHOGS, newNegHOGS, newPosRECTS, newNegRECTS] = ...
        tryOnNewImage(im, W, posRECTexamples, xMean);
    
    posHOGS = cat(2,posHOGS,newPosHOGS);
    negHOGS = cat(2,negHOGS,newNegHOGS);
    posRECTexamples = cat(1, posRECTexamples, newPosRECTS);
    
    % now reconstruct the examples in such a way that Agata can use them
    for jx = 1:size(newPosRECTS,1)
        [hog rectData] = makeHOGandRECT(im,newPosRECTS(jx,:));
        rectData.fName = fName;
        posRECTS{end+1} = rectData;
    end
    for jx = 1:size(newNegRECTS,1)
        [hog rectData] = makeHOGandRECT(im,newNegRECTS(jx,:));
        rectData.fName = fName;
        negRECTS{end+1} = rectData;
    end
    
saveMATfile = [dirName '/rects.mat'];
save(saveMATfile,'posRECTS','negRECTS');
end

% do it one last time:
    [W, xMean] = doHOGsvm(posHOGS, negHOGS);

    
%% shrink the posRECTS and negRECTS data structure (remove the pixel data)

pR = {};
nR = {};
for ix = 1:length(posRECTS)
    rD.fName = posRECTS{ix}.fName;
    rD.r = posRECTS{ix}.r;
    pR{ix} = rD;
end

for ix = 1:length(negRECTS)
    rD.fName = negRECTS{ix}.fName;
    rD.r = negRECTS{ix}.r;
    nR{ix} = rD;
end

%
%whichCamera = 10888;
svmWeightVector = W;
posRECTS = pR;
negRECTS = nR;
saveMATfile = [num2str(whichCamera) 'rects.mat'];
save(saveMATfile,'posRECTS','negRECTS','svmWeightVector','whichCamera');









